/*
 * ArchivoRuta.cpp
 *
 *  Created on: 31/03/2011
 */

#include "ArchivoRuta.h"
#include <string>

ArchivoRuta::ArchivoRuta(string unNombreDeArchivoRuta) {

	this->nombreDeArchivoRuta = unNombreDeArchivoRuta;

	//Crea el archivo y lo deja abierto en modo lectura - escritura binario
	this->archivoRuta.open(nombreDeArchivoRuta.c_str(), ios::in | ios::out | ios::binary);

	this->archivoRuta.close();
//
//	/* determina si tuvo éxito la apertura del archivo */
//	if (!this->archivoRuta.is_open()) {
//
//		/* limpia los flags de control de estado del archivo */
//		this->archivoRuta.clear();
//		throw string("El archivo no pudo ser abierto");
//	}

}

void ArchivoRuta::abrirParaLeer() {
	//Abre el archivo y lo deja abierto en modo lectura binaria
	this->archivoRuta.open(nombreDeArchivoRuta.c_str(), ios::in  | ios::binary);

	/* determina si tuvo éxito la apertura del archivo */
	if (!this->archivoRuta.is_open()) {

		/* limpia los flags de control de estado del archivo */
		this->archivoRuta.clear();
		throw string("El archivo no pudo ser abierto para lectura");
	}
}

void ArchivoRuta::abrirParaEscribir() {
	//Abre el archivo y lo deja abierto en modo lectura binaria
	this->archivoRuta.open(nombreDeArchivoRuta.c_str(), ios::out | ios::app  | ios::binary);

	/* determina si tuvo éxito la apertura del archivo */
	if (!this->archivoRuta.is_open()) {

		/* limpia los flags de control de estado del archivo */
		this->archivoRuta.clear();
		throw string("El archivo no pudo ser abierto para lectura");
	}
}



int ArchivoRuta::escribir(RegistroRuta* unRegistroRuta) {

	//Obtengo la longitud del registro
	int longitudDelRegistro = unRegistroRuta->obtenerLongitud();

	//Me posiciono al final del archivo
	this->archivoRuta.seekp(0, ios_base::end);

	//Guardo el offset para usarlo como id al registro guardado
	int offset = this->archivoRuta.tellp();

	//Grabo como primer campo la longitud del registro
	this->archivoRuta.write((char*) &longitudDelRegistro, sizeof(int));

	//Paso el registro a binario
	char* binario = unRegistroRuta->aBinario();

	//Grabo como segundo campo el registro
	this->archivoRuta.write(binario, longitudDelRegistro);

	//Devuelvo el id al registro grabado
	return offset;

}

RegistroRuta* ArchivoRuta::leer(int idRegistroRuta) {

	/*El id del registro me da el offset donde se encuentra el
	 * primer campo a leer que es la longitud del registro */
	//Me posiciono en el campo longitud
	this->archivoRuta.seekg(idRegistroRuta, ios_base::beg);

	//Obtengo la longitud del registro
	int longitudDelRegistro;
	this->archivoRuta.read((char*) &longitudDelRegistro,sizeof(int));

	//Leo el registro en binario
	char* binario = new char[longitudDelRegistro];
	this->archivoRuta.read(binario,longitudDelRegistro);

	//Obtengo el registro ruta
	RegistroRuta* registroRuta = new RegistroRuta();
	//Convierto el registro desde binario a un objeto RegistroRuta
	registroRuta->desdeBinario(binario, longitudDelRegistro);

	return registroRuta;

}

RegistroRuta* ArchivoRuta::leerSiguiente() {

	//Obtengo la longitud del registro
	int longitudDelRegistro;
	this->archivoRuta.read((char*) (&longitudDelRegistro),sizeof(int));

	if(longitudDelRegistro == 0)
		return NULL;

	//Leo el registro en binario
	char* binario = new char[longitudDelRegistro];
	this->archivoRuta.read(binario,longitudDelRegistro);

	//Obtengo el registro ruta
	RegistroRuta* registroRuta = new RegistroRuta();
	//Convierto el registro desde binario a un objeto RegistroRuta
	registroRuta->desdeBinario(binario, longitudDelRegistro);

	return registroRuta;

}

void ArchivoRuta::cerrar() {
	this->archivoRuta.close();
}

ArchivoRuta::~ArchivoRuta() {
}

bool ArchivoRuta::estaCerrado(){
	return (!this->archivoRuta.is_open());
}

void ArchivoRuta::sobreescribir(){
	//Trunca el archivo
	this->archivoRuta.open(nombreDeArchivoRuta.c_str(), ios::in | ios::out | ios::trunc | ios::binary);

	this->archivoRuta.close();

}

void ArchivoRuta::marcarFin(){
	int longitudDelRegistro = 0;
	this->archivoRuta.write((char*) (&longitudDelRegistro), sizeof(int));
}

void ArchivoRuta::escribirCantidadTotal(int cantidadTotal){
	//Me posiciono al final del archivo
	this->archivoRuta.write((char*) (&cantidadTotal),sizeof(int));
}

int ArchivoRuta::leerCantidadTotal(){
	int cantidadTotal;
	this->archivoRuta.read((char*) (&cantidadTotal),sizeof(int));

	return cantidadTotal;
}
